package com.caocaog.market.finance.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.caocaog.market.finance.enums.WithdrawStatus;
import com.caocaog.market.finance.enums.WithdrawType;
import com.caocaog.market.finance.service.FinanceGroupService;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.util.DateUtils;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

import static com.caocaog.market.finance.enums.WithdrawStatus.FULLY_WITHDRAW;
import static com.caocaog.market.finance.enums.WithdrawType.MERCHANT;
import static com.caocaog.market.finance.enums.WithdrawType.SITE;

/**
 * 提现组
 */
@Data
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@TableName("mk_finance_group")
public class FinanceGroup implements Serializable {
    private static final long serialVersionUID = 1L;

    @TableId(type = IdType.AUTO)
    private Long id;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    protected LocalDateTime createTime;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    protected LocalDateTime updateTime;
    @TableLogic
    protected Integer deleted;


    /**
     * 提现组编号
     */
    private String groupNo;

    /**
     * 生成提现组编号
     */
    public FinanceGroup generateGroupNo() {
        if (groupNo == null)
            return setGroupNo(DateUtils.date2Str(new Date(), DateUtils.yymmddhhmmssSSSSS.get()));
        return this;
    }


    /**
     * 提现总金额
     */
    private transient BigDecimal totalAmount;

    /**
     * 生成提现总金额
     */
    public FinanceGroup generateTotalAmount() {
        Assert.isTrue(financeLines != null && !financeLines.isEmpty(), "提现行不能为空");

        BigDecimal amount = BigDecimal.ZERO;
        for (FinanceLine financeLine : financeLines) {
            if (type == MERCHANT) {
                amount = amount.add(financeLine.getShopAmount());
            } else if (type == SITE) {
                amount = amount.add(financeLine.getSiteAmount());
            }
        }

        return setTotalAmount(amount);
    }


    /**
     * 提现类型 1商家 2分站
     */
    private WithdrawType type;
    /**
     * 提现状态 1待审核 2待转账 3已提现 -1驳回 -2转账失败 默认1
     */
    private WithdrawStatus status;


    /**
     * 分站ID
     */
    @Dict(dictTable = "mk_site_basic",dicText = "name",dicCode = "id")
    private String siteId;
    /**
     * 商家id
     */
    @Dict(dictTable = "mk_merchant_basic", dicText = "name", dicCode = "id")
    private String merchantId;
    /**
     * 店铺id
     */
    @Dict(dictTable = "mk_shop_basic", dicText = "name", dicCode = "id")
    private String shopId;


    /**
     * 支付宝账号
     */
    private String alipayAccount;
    /**
     * 支付宝实名认证姓名
     */
    private String alipayName;
    /**
     * 分站提现时的支付宝订单号
     */
    private String alipayNo;
    /**
     * 分站提现时支付宝返回的回调信息
     */
    private String alipayCallbackInfo;
    /**
     * 审核驳回原因/转账失败原因
     */
    private String rejectReason;


    /**
     * 申请时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime applicationTime;
    /**
     * 审核时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime auditTime;
    /**
     * 转账时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime transferTime;

    /**
     * 提现行集合 {@link FinanceGroupService#queryFinanceGroupPage(Page, FinanceGroup) 查询提现组分页}时使用
     */
    private transient List<FinanceLine> financeLines;

    public FinanceGroup setFinanceLines(List<FinanceLine> financeLines) {
        this.financeLines = financeLines;
        return generateTotalAmount();
    }


    /**
     * 查询参数
     */
    private transient String orderNo;
    private transient String applicationTimeFrom;
    private transient String applicationTimeTo;
    private transient String siteName;


    /**
     * 是可删除的（前端所需的判断参数）
     */
    private transient Boolean deletable;
    public FinanceGroup setDeletable() {
        return setDeletable(isDeletable(this));
    }

    // 是可删除的，只要不是「已提现」的都是可删除的
    public static boolean isDeletable(FinanceGroup financeGroup) {
        return financeGroup.status != FULLY_WITHDRAW;
    }


    /**
     * 清除数据
     * 在{@link FinanceGroupService#updateFinanceGroup(FinanceGroup) 更新提现组}时，避免修改到固定字段
     */
    public FinanceGroup clearFields() {
        createTime = null;
        updateTime = null;
        deleted = null;
        type = null;
        siteId = null;
        merchantId = null;
        shopId = null;
        groupNo = null;
        return this;
    }

}
